package cn.chencq.utils.redis;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class RedisLock {

	@Autowired
	private RedisUtils redis;

	/**
	 * 尝试获取分布式锁
	 * 
	 * @param jedis
	 *            Redis客户端
	 * @param key
	 *            锁
	 * @param expireTime
	 *            过期时间(毫秒数)
	 * @return 是否获取成功
	 */
	public boolean tryGetDistributedLock(String key, String expireTime) {
		if (redis.setIfAbsent(key, expireTime)) {// setnx成功,说明key不存在
			return true;
		}

		// 判断锁超时 - 防止原来的操作异常，没有运行解锁操作 防止死锁
		String currentValue = redis.get(key);
		// 如果锁过期
		if (StringUtils.isNotBlank(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()) {// currentValue不为空且小于当前时间
			// 获取上一个锁的时间value
			String oldValue = redis.getAndSet(key, expireTime);// 对应getset，如果key存在

			if (StringUtils.isNotBlank(oldValue) && oldValue.equals(currentValue)) {
				// oldValue不为空且oldValue等于currentValue，也就是校验是不是上个对应的时间戳，也是防止并发
				return true;
			}
		}
		return false;
	}

	/**
	 * 解锁
	 * 
	 * @param jedis
	 *            Redis客户端
	 * @param key
	 *            锁
	 * @param expireTime
	 *            过期时间(毫秒数)
	 * @return 是否获取成功
	 */
	public void unlock(String key, String expireTime) {
		try {
			String currentValue = redis.get(key);
			if (StringUtils.isNotBlank(currentValue) && currentValue.equals(expireTime)) {
				redis.delete(key); // 删除key
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
